#ifndef FND_GAME_INDEX_RESOURCE_HPP
#define FND_GAME_INDEX_RESOURCE_HPP
#include <vector>
#include <map>
#include <string>
#include <stdexcept>

namespace FndGame2D {
  template<typename T, typename K = std::string>
  class  index_resource_manager {
  public:
    typedef T value_type ;
    typedef K key_type ;
    typedef std::vector<value_type> resource_vectror ;
    typedef std::map<key_type, std::vector<std::size_t> > resource_index ;
  private:
    resource_index m_index_resources ;
    resource_vectror m_resources ;
  public:
    void add_value(const T& value) {
      m_resources.push_back(value) ;
    }
    const T& get_value(const K& key, std::size_t index) const {
      typename resource_index::const_iterator it(m_index_resources.find(key)) ;
      if(it == m_index_resources.end())
	throw std::range_error("out of bound") ;
      return m_resources.at((*it).second.at(index)) ;
    }
    void add_index(const K& key) {
      m_index_resources[key] ;
    }
    void add_index(const K& key, std::size_t id) {
      m_index_resources[key].push_back(id) ;
    }
    std::size_t get_index_number(const K& key) const {
      check_valid(key) ;
      return (*m_index_resources.find(key)).second.size() ;
    }
    void clear_index(const K& key) {
      m_index_resources.erase(key) ;
    }
    void clear_index() {
      m_index_resources.clear() ;
    }
    void clear_values() {
      m_resources.clear() ;
    }
    std::size_t value_number() const {
      return m_resources.size() ;
    }
    bool has_index(const K& key) const {
      return m_index_resources.find(key) != m_index_resources.end() ;
    }

  private:
    void check_valid(const K& key)const  {
      typename resource_index::const_iterator it(m_index_resources.find(key)) ;
      if(it == m_index_resources.end())
	throw std::range_error("out of bound") ;
    }

  } ;
}
#endif
